package com.sx.admin.controller;

import com.sx.core.CardConstants;
import com.sx.core.exception.UpdloadFileException;
import com.sx.core.exception.UpdloadFileNameException;
import com.sx.core.exception.UpdloadFileSizeException;
import com.sx.core.vo.JsonReaderResponse;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Random;

/**
 * Created by lihao on 7/4/14.
 */
public class BaseController implements CardConstants {
    protected final transient Log logger = LogFactory.getLog(getClass());
    @Autowired
    protected ApplicationContext context;
    public static String uploadPath=System.getProperty("upPath");
    public static String imgUrl=System.getProperty("imgUrl");
    public static final String limit="limit";
    public static final String page="page";
    public static final Integer LIMIT=20;
    public static final Integer DefaultPage=1;
    public final static String YMD="yyyy-MM-dd";
    public final static String YM="yyyy-MM";
    public final static String YMDHMS="yyyy-MM-dd HH:mm:ss";
    @Autowired
    protected JdbcTemplate jdbcTemplate;
    @Autowired
    protected NamedParameterJdbcTemplate namedParameterJdbcTemplate;



    protected final static JsonReaderResponse json=new JsonReaderResponse();


    @ExceptionHandler
    public JsonReaderResponse exp(HttpServletRequest request, Exception ex) {
        logger.error("execute "+getClass()+"",ex);
        return new JsonReaderResponse("服务器异常", CardConstants.SERVER_ERROR_CODE);
    }



    public Date parseDate(HttpServletRequest request, String filed){
        try {
            String value=request.getParameter(filed);
            Date date = DateUtils.parseDate(value, new String[]{YM,YMD, YMDHMS});
            return date;
        } catch (Exception e) {
        }
        return null;
    }

    public Long parseLong(HttpServletRequest request, String filed){
        String value=request.getParameter(filed);
        if(NumberUtils.isNumber(value))
            return NumberUtils.toLong(value);
        return null;
    }
    public Integer parseInteger(HttpServletRequest request, String filed){
        String value=request.getParameter(filed);
        if(NumberUtils.isNumber(value))
            return Integer.parseInt(value);
        return null;
    }
    public Short parseShort(HttpServletRequest request, String filed){
        String value=request.getParameter(filed);
        if(NumberUtils.isNumber(value))
            return Short.parseShort(value);
        return null;
    }
    public Double parseDouble(HttpServletRequest request, String filed){
        String value=request.getParameter(filed);
        if(NumberUtils.isNumber(value))
            return Double.parseDouble(value);
        return null;
    }
    public Float parseFloat(HttpServletRequest request, String filed){
        String value=request.getParameter(filed);
        if(NumberUtils.isNumber(value))
            return Float.parseFloat(value);
        return null;
    }

    public Boolean parseBoolean(HttpServletRequest request, String filed){
        String value=request.getParameter(filed);
        if(StringUtils.isNotEmpty(value)){
            return toBooleanObject(value);
        }
        return null;
    }
    private Boolean toBooleanObject(String str) {
        if ("true".equalsIgnoreCase(str)) {
            return Boolean.TRUE;
        } else if ("false".equalsIgnoreCase(str)) {
            return Boolean.FALSE;
        } else if ("on".equalsIgnoreCase(str)) {
            return Boolean.TRUE;
        } else if ("off".equalsIgnoreCase(str)) {
            return Boolean.FALSE;
        } else if ("yes".equalsIgnoreCase(str)) {
            return Boolean.TRUE;
        } else if ("no".equalsIgnoreCase(str)) {
            return Boolean.FALSE;
        } else if("1".equalsIgnoreCase(str)){
            return Boolean.TRUE;
        } else if("0".equalsIgnoreCase(str)){
            return Boolean.FALSE;
        } else if("y".equalsIgnoreCase(str)){
            return Boolean.TRUE;
        } else if("n".equalsIgnoreCase(str)){
            return Boolean.FALSE;
        }
        return null;
    }

    public String getMessage(String key,HttpServletRequest request) {
        return context.getMessage(key, null, Locale.SIMPLIFIED_CHINESE);
    }
    public String getMessage(String key, Object[] args) {
        return context.getMessage(key, args, Locale.getDefault());
    }
    public String getMessage(String key, Locale locale) {
        return context.getMessage(key, null, locale);
    }
    public String getMessage(String key, Object[] args, Locale locale) {
        return context.getMessage(key, args, locale);
    }
    public String getZhMessage(String key) {
        return context.getMessage(key, null, Locale.SIMPLIFIED_CHINESE);
    }
    public String getZhMessage(String key,Object[] args) {
        return context.getMessage(key, args, Locale.SIMPLIFIED_CHINESE);
    }
    public Boolean isEmpty(HttpServletRequest request, String filed){
        return StringUtils.isEmpty(request.getParameter(filed));
    }
    public Boolean isNotEmpty(HttpServletRequest request, String filed){
        return StringUtils.isNotEmpty(request.getParameter(filed));
    }
    public Boolean isNumber(HttpServletRequest request, String filed){
        return NumberUtils.isNumber(request.getParameter(filed));
    }
    public String obtain(HttpServletRequest request, String params){
        String str= request.getParameter(params);
        return str!=null?str.trim():str;
    }
    public Integer obtainLimit(HttpServletRequest request){
        String li=request.getParameter(limit);
        if(NumberUtils.isNumber(li)){
            return Integer.valueOf(li);
        }
        return  LIMIT;
    }
    public Integer obtainPage(HttpServletRequest request){
        String li=request.getParameter(page);
        if(NumberUtils.isNumber(li)){
            Integer p=Integer.valueOf(li);
            return Math.max(DefaultPage,p);
        }
        return  DefaultPage;
    }


    public Map<String,CustomMultipartFile> getFile(HttpServletRequest request, String relativelyDir, long size, String... fileTypes) throws UpdloadFileException,UpdloadFileNameException,UpdloadFileSizeException {
        Map<String,CustomMultipartFile> fileHashMap=new HashMap<String, CustomMultipartFile>();
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Iterator list             = multipartRequest.getFileNames();
        while (list.hasNext()) {
            File fileOnServer = null;
            String fileName=null;
            String controlName = list.next().toString();
            String dir=new StringBuilder().append(uploadPath).append(File.separator).append(relativelyDir).toString();
            if(StringUtils.isEmpty(dir)){
                continue;
            }
            dir=FilenameUtils.normalize(dir);
            MultipartFile file        = multipartRequest.getFile(controlName);
            CommonsMultipartFile cmf         = (CommonsMultipartFile) file;
            DiskFileItem fileItem    = (DiskFileItem) cmf.getFileItem();
            fileName=fileItem.getName();
            if(StringUtils.isEmpty(fileName)){
                continue;
            }
            String ext=getExtension(fileName);
            if(fileTypes!=null && fileTypes.length>0 && !ArrayUtils.contains(fileTypes,ext)){
                throw new UpdloadFileNameException(fileName);
            }
            long fileItemSize=fileItem.getSize();
            if(fileItemSize>size){
                throw new UpdloadFileSizeException(fileName);
            }

            String str         = randomName(fileName);
            File attachDir = randomAbsolutePath(request, dir);
            fileOnServer      = new File(attachDir,str);
            try {
                fileItem.write(fileOnServer);
            } catch (Exception e) {
                try {
                    FileUtils.forceDelete(fileOnServer);
                } catch (IOException e1) {
                }
                logger.error("write file throw exception",e);
                throw new UpdloadFileException(e);
            }
            if(fileOnServer!=null){
                CustomMultipartFile customMultipartFile=new CustomMultipartFile(fileOnServer,controlName).setName(fileName).setUrl(toHttpUrl(request, relativelyDir, str)).setRelativePath(toRelativePath(dir, str));
                fileHashMap.put(controlName, customMultipartFile);
            }
        }
        return fileHashMap;
    }


    private String toRelativePath(String dir,String fileName){
        return FilenameUtils.normalize(new StringBuilder().append(dir).append(File.separator).append(fileName).toString());
    }
    public String toHttpUrl(HttpServletRequest request, String dir, String fileName){
        dir=dir.replaceAll("\\\\","/");
        return new StringBuilder().append(dir).append("/").append(fileName).toString();
    }
    public File randomAbsolutePath(HttpServletRequest request, String dir){
        File fileDir = new File(dir);
        if (fileDir.exists() == false) {
            fileDir.mkdirs();
        }
        return fileDir;
    }
    public String randomName(String fileName) {
        Random random = new Random();
        return new StringBuilder().append(random.nextInt(10000)).append(System.currentTimeMillis()).append(getExtension(fileName)).toString();
    }
    public String getExtension(String fileName) {
        return fileName.substring(fileName.lastIndexOf("."));
    }

    public static class CustomMultipartFile{
        private String url;
        private String relativePath;
        private String key;
        private String name;
        private File file;

        public CustomMultipartFile(File file,String key) {
            this.file=file;
            this.key=key;
        }
        public String getUrl() {
            return url;
        }
        public String getName(){
            return name;
        }

        public CustomMultipartFile setName(String name) {
            this.name = name;
            return this;
        }

        public String getAbsolutePath(){
            return this.file.getAbsolutePath();
        }


        public CustomMultipartFile setUrl(String url) {
            this.url = url;
            return this;
        }

        public String getRelativePath() {
            return relativePath;
        }

        public CustomMultipartFile setRelativePath(String relativePath) {
            this.relativePath = relativePath;
            return this;
        }

        public File getFile() {
            return file;
        }

        public String getKey() {
            return key;
        }
    }

    public void download(File file, HttpServletRequest request, HttpServletResponse response, String sheetName) {
        OutputStream fOut = null;
        try {
            fOut = response.getOutputStream();
//            response.setCharacterEncoding("application/ms-excel;charset=UTF-8");
//            response.setCharacterEncoding("ms-excel/html;charset=UTF-8");
            response.setContentType("application/ms-excel");
            response.setContentType("application/octet-stream;charset=UTF-8");

            String finalExportZipFileName = sheetName;
            if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {
                finalExportZipFileName = URLEncoder.encode(sheetName, "UTF-8");
            } else {
                finalExportZipFileName = new String(sheetName.getBytes("UTF-8"), "ISO-8859-1");
            }
            String ext=FilenameUtils.getExtension(file.getName());

            finalExportZipFileName = finalExportZipFileName + "."+ext;
            response.addHeader("Content-Disposition", "attachment;Filename=" + finalExportZipFileName);
            byte[] bytes = FileUtils.readFileToByteArray(file);
            fOut.write(bytes);
            fOut.flush();
        } catch (IOException e) {
            logger.error("export student error", e);
        } finally {

            if (fOut != null) {
                try {
                    fOut.close();
                } catch (IOException e) {
                }
            }
        }
    }





}
